package repositories

import (
	"sort"

	"gitee.com/kessil/chicory/internal/models"
	"xorm.io/xorm"
)

type PermissionRepository struct {
	*Repository[models.Permission]
	db *xorm.Engine
}

func NewPermissionRepository(db *xorm.Engine) *PermissionRepository {
	return &PermissionRepository{
		Repository: NewRepository[models.Permission](db),
		db:         db,
	}
}

// 权限树相关操作

// GetAllPermissionTree 获取所有权限的树形结构
func (r *PermissionRepository) GetAllPermissionTree() ([]*models.Permission, error) {
	var permissions []*models.Permission
	err := r.db.Asc("order").Find(&permissions)
	if err != nil {
		return nil, err
	}

	return r.buildPermissionTree(permissions), nil
}

// GetAllPermissionTree 获取所有菜单权限的树形结构
func (r *PermissionRepository) GetAllPermissionMenuTree() ([]*models.Permission, error) {
	var permissions []*models.Permission
	err := r.db.Table("permission").Where("type = ?", "MENU").Asc("order").Find(&permissions)
	if err != nil {
		return nil, err
	}

	return r.buildPermissionTree(permissions), nil
}

// GetPermissionTreeByRoleId 根据角色ID获取权限树
func (r *PermissionRepository) GetPermissionTreeByRoleId(roleId int64) ([]*models.Permission, error) {
	permissions, err := r.GetPermissionsByRoleId(roleId)
	if err != nil {
		return nil, err
	}
	return r.buildPermissionTree(permissions), nil
}

// GetPermissionsTreeByRoleIds 根据多个角色ID获取权限树（合并去重）
func (r *PermissionRepository) GetPermissionsTreeByRoleIds(roleIds []int64) ([]*models.Permission, error) {
	permissions, err := r.GetPermissionsByRoleIds(roleIds)
	if err != nil {
		return nil, err
	}

	return r.buildPermissionTree(permissions), nil
}

// GetPermissionsByRoleId 根据角色ID获取权限列表（平铺）
func (r *PermissionRepository) GetPermissionsByRoleId(roleId int64) ([]*models.Permission, error) {
	var permissions []*models.Permission

	err := r.db.Table("permission").
		Join("INNER", "role_permission", "permission.id = role_permission.permissionId").
		Where("role_permission.roleId = ?", roleId).
		Asc("permission.id").
		Find(&permissions)

	if err != nil {
		return nil, err
	}

	return permissions, nil
}

// GetPermissionsByRoleIds 根据多个角色ID获取权限列表（合并去重）
func (r *PermissionRepository) GetPermissionsByRoleIds(roleIds []int64) ([]*models.Permission, error) {
	if len(roleIds) == 0 {
		return []*models.Permission{}, nil
	}

	var permissions []*models.Permission

	err := r.db.Table("permission").
		Join("INNER", "role_permission", "permission.id = role_permission.permissionId").
		In("role_permission.roleId", roleIds).
		Distinct("permission.id").
		Asc("permission.id").
		Find(&permissions)

	if err != nil {
		return nil, err
	}

	return permissions, nil
}

// buildPermissionTree 构建权限树形结构
func (r *PermissionRepository) buildPermissionTree(permissions []*models.Permission) []*models.Permission {
	// 创建权限映射表
	permissionMap := make(map[int64]*models.Permission)

	// 初始化所有权限节点
	for _, perm := range permissions {
		// 创建新的指针，避免引用问题
		newPerm := &models.Permission{
			Id:          perm.Id,
			Name:        perm.Name,
			Code:        perm.Code,
			Type:        perm.Type,
			ParentId:    perm.ParentId,
			Path:        perm.Path,
			Redirect:    perm.Redirect,
			Icon:        perm.Icon,
			Component:   perm.Component,
			Layout:      perm.Layout,
			KeepAlive:   perm.KeepAlive,
			Method:      perm.Method,
			Description: perm.Description,
			Show:        perm.Show,
			Enable:      perm.Enable,
			Order:       perm.Order,
			Created:     perm.Created,
			Updated:     perm.Updated,
			Deleted:     perm.Deleted,
			Children:    []*models.Permission{},
		}
		permissionMap[newPerm.Id] = newPerm
	}
	// 构建树形结构
	var rootNodes []*models.Permission

	for _, perm := range permissionMap {
		if perm.ParentId == 0 {
			// 根节点
			rootNodes = append(rootNodes, perm)
		} else {
			// 子节点，找到父节点并添加
			if parent, exists := permissionMap[perm.ParentId]; exists {
				parent.Children = append(parent.Children, perm)
			}
		}
	}

	// 对根节点和子节点进行排序
	r.sortPermissionTree(rootNodes)
	return rootNodes
}

// sortPermissionTree 递归排序权限树
func (r *PermissionRepository) sortPermissionTree(nodes []*models.Permission) {
	if len(nodes) == 0 {
		return
	}

	// 对当前层级按sort字段排序
	sort.Slice(nodes, func(i, j int) bool {
		return nodes[i].Order < nodes[j].Order
	})

	// 递归排序子节点
	for _, node := range nodes {
		if len(node.Children) > 0 {
			r.sortPermissionTree(node.Children)
		}
	}
}

// CheckUserPermission 检查用户是否拥有某个权限
func (r *PermissionRepository) CheckUserPermission(userId int64, permissionCode string) (bool, error) {
	// 获取用户的所有角色
	userRepo := NewUserRepository(r.db)
	roles, err := userRepo.GetUserRoles(userId)
	if err != nil {
		return false, err
	}

	if len(roles) == 0 {
		return false, nil
	}

	// 提取角色ID
	roleIds := make([]int64, len(roles))
	for i, role := range roles {
		roleIds[i] = role.Id
	}

	// 检查是否有该权限
	var count int64
	count, err = r.db.Table("permission").
		Join("INNER", "role_permission", "permission.id = role_permission.permissionId").
		In("role_permission.roleId", roleIds).
		Where("permission.code = ?", permissionCode).
		Count()

	if err != nil {
		return false, err
	}

	return count > 0, nil
}

// AddRolePermission 为角色添加权限
func (r *PermissionRepository) AddRolePermission(roleId, permissionId int64) error {
	// 检查是否已存在
	exists, err := r.db.Table("role_permission").
		Where("roleId = ? AND permissionId = ?", roleId, permissionId).
		Exist()

	if err != nil {
		return err
	}

	if exists {
		return nil // 已存在，不重复添加
	}

	rolePermission := &models.RolePermission{
		RoleId:       roleId,
		PermissionId: permissionId,
	}

	_, err = r.db.Insert(rolePermission)
	return err
}

// RemoveRolePermission 移除角色的权限
func (r *PermissionRepository) RemoveRolePermission(roleId, permissionId int64) error {
	_, err := r.db.Table("role_permission").
		Where("roleId = ? AND permissionId = ?", roleId, permissionId).
		Delete()

	return err
}

// GetRolePermissions 获取角色的所有权限
func (r *PermissionRepository) GetRolePermissions(roleId int64) ([]*models.Permission, error) {
	return r.GetPermissionsByRoleId(roleId)
}

// GetRolePermissions 获取角色的所有权限
func (r *PermissionRepository) GetButtonPermissionByParentId(parentId int64) ([]*models.Permission, error) {
	var perms []*models.Permission
	if err := r.db.Where("parentId = ?", parentId).Find(&perms); err != nil {
		return nil, err
	}
	return perms, nil
}
